home *** CD-ROM | disk | FTP | other *** search
- {$C-,V-,K-}
- (****************************************************************************)
- (* *)
- (* Author: Paul Meiners *)
- (* P & M Software Company *)
- (* 9350 Country Creek #30 *)
- (* Houston, Texas 77036 *)
- (* *)
- (* Phone: (713) 772-2090 *)
- (* *)
- (* Date: March 3, 1985 *)
- (* *)
- (* Language: Turbo PASCAL version 3.00B *)
- (* *)
- (* Remarks: This program provides basic terminal emulation with capture *)
- (* to disk and XMODEM file transfer. Uses interrupt driven *)
- (* serial I/O with circular queues. Uses a removable window *)
- (* system. *)
- (* *)
- (****************************************************************************)
-
- program
- TMODEM23;
-
- type
- strtype = string[255];
- string80 = string[80];
- string40 = string[40];
- string30 = string[30];
- string10 = string[10];
- alt_char_array = array[ 96..127 ] of byte;
-
- const
- sin_buf_size = 10240;
- sin_buf_fill_lim = 8192;
- sin_buf_drain_lim = 4096;
- sout_buf_size = 512;
- capture_buf_size = 1024;
- max_xmodem_buffers = 64;
- max_dial_entries = 16;
- SOH = ^A;
- CAN = ^X;
- NAK = ^U;
- ACK = ^F;
- EOT = ^D;
- CR = ^M;
- LF = ^J;
- CRLF = ^M^J;
- ESC = #27;
- NUL = #00;
- FF = ^L;
- BS = ^H;
- TAB = ^I;
- default_stopbits : integer = 1;
- default_databits : integer = 8;
- default_parity : integer = 0; { 0=None, 1=Even, 2=Odd }
- default_baud : integer = 1200;
- wait_increment : integer = 333; { 1/3 of a second. }
- datasegment : integer = 0;
- XON : integer = 17; { XON is a DC1 character. }
- XOFF : integer = 19; { XOFF is a DC3 character. }
- dial_pre_str : string40 = 'ATDT ';
- dial_post_str : string10 = '|'; { | is replaced by CR }
- modem_init_str : string40 = 'AT S0=0|';
- speaker_off : string40 = 'AT M0|';
- speaker_on : string40 = 'AT M1|';
- forced_carrier : string10 = 'FALSE';
- vt100_mode : string10 = 'FALSE';
- redial_time : integer = 60;
- carrier_timeout : integer = 35;
- alt_character : alt_char_array = ( 4,97,98,99,100,101,102,241,104,105,
- 217,191,218,192,197,196,196,196,196,196,195,180,193,
- 194,179,243,242,227,216,156,250,127 );
-
- type
- sin_buffer_type = array[1..sin_buf_size] of byte;
- sout_buffer_type = array[1..sout_buf_size] of byte;
- func_buffer_type = array[1..40] of string80;
- capture_ptr_type = ^capture_record;
- capture_record = record
- capture_store_ptr : integer;
- capture_buffer : array[1..capture_buf_size] of char;
- capture_next : capture_ptr_type;
- end;
- xmodem_buf = array[1..128] of char;
- xmodem_table = array[1..max_xmodem_buffers] of xmodem_buf;
- registerset = record
- AX,BX,CX,DX,BP,DI,SE,DS,ES,Flags : integer;
- end;
- dialrec = record
- bbs_name : string30;
- bbs_number : string30;
- bbs_baud : integer;
- bbs_parity : integer;
- bbs_databits : integer;
- bbs_stopbits : integer;
- end;
- dialarray = record
- no_of_dial_entries : integer;
- dir_entries :
- array[1..max_dial_entries] of dialrec;
- end;
- sort_ptr_type = ^dialsort;
- dialsort = record
- sort_rec : dialrec;
- sort_next : sort_ptr_type;
- end;
- var
- rand : real;
- sin_buf_fill_cnt : integer;
- sin_xoff : boolean;
- sin_buffer_ptr : ^sin_buffer_type;
- sin_store_ptr : integer;
- sin_read_ptr : integer;
- sout_buffer_ptr : ^sout_buffer_type;
- sout_store_ptr : integer;
- sout_read_ptr : integer;
- sout_int_off : boolean;
- turn_IRQ_on : byte;
- turn_IRQ_off : byte;
- IRQ_vector_ofs : integer;
- IRQ_vector_seg : integer;
- hold_vector_ofs : integer;
- hold_vector_seg : integer;
- base_com_addr : integer absolute $0000:$0400;
- int_enable_reg : integer;
- int_ident_reg : integer;
- int_ident : byte;
- line_control_reg : integer;
- modem_control_reg : integer;
- line_status_reg : integer;
- line_status : byte;
- modem_status_reg : integer;
- sync_time : integer;
- xmodem_table_ptr : ^xmodem_table;
- xmodem_buf_cnt : integer;
- xmodem_ptr : integer;
- xmodem_rd : integer;
- continue_transfer : boolean;
- capture_flag : boolean;
- capture_warning : boolean;
- capture_first : capture_ptr_type;
- capture_curr : capture_ptr_type;
- printer_on : boolean;
- sort_curr : sort_ptr_type;
- sort_first : sort_ptr_type;
- sort_prev : sort_ptr_type;
- exit_program : boolean;
- func_key : ^func_buffer_type;
- keyfile : text;
- block_count : integer;
- error_count : integer;
- filename : string80;
- recv_file : file;
- xmit_file : file;
- textfile : text;
- textimage : strtype;
- dial_drive : integer;
- dial_PATH : string80;
- cnf_PATH : string80;
- dialfile : file of dialarray;
- dial_dir : dialarray;
- dialarray_number : integer;
- dial_str : string40;
- redial_number : string40;
- redial_name : string30;
- baud : integer;
- stopbits : integer;
- databits : integer;
- par : integer;
- kbd_char : char;
- a_key : string[2];
- regs : registerset;
- half_duplex : boolean;
- ascii_mode : boolean;
- escape_mode : boolean;
- escape_number : byte;
- escape_register : array[1..50] of byte;
- escape_str : strtype;
- escape_type : char;
- line_drawing_chars : boolean;
- ok : boolean;
- parity_ch : string10;
- baud_ch : string10;
- stop_ch : string10;
- data_ch : string10;
- FGcolor,BGcolor : integer;
- FG,BG : integer;
- white_shade : integer;
- scale : array[ 0..20 ] of real;
- notes : array[ 1..84 ] of integer;
- factor : array[ 0..6 ] of real;
- tempo : real;
- note_length : integer;
- octave : integer;
- dots : integer;
- dnote : array[ 0..6 ] of real;
- music_mode : real;
- rest_mode : real;
- silent_mode : boolean;
- monitor_mode : boolean;
- tune_number : integer;
- time_fix : string10;
- curr_time : string10;
- start_time : string10;
- dial_time : string10;
- a_second : integer;
- yes_no : string[4];
-
- {$I BASIC.INC}
- {$I RWINDOW.INC}
- (****************************************************************************)
- (* COMMAND DISTRIBUTOR *)
- (****************************************************************************)
- procedure
- exec_command(ch : char); FORWARD;
-
- (****************************************************************************)
- (* WAIT FOR A KEY *)
- (****************************************************************************)
- procedure
- wait_for_key;
- begin
- write(' Press ANY key to continue...');
- repeat
- repeat
- a_key := inkey;
- until a_key <> '';
- if length(a_key) = 2 then begin
- exec_command(a_key[2]);
- a_key := '';
- end;
- until length(a_key) = 1;
- end;
-
- (****************************************************************************)
- (* REWRITE CONFIG FILE *)
- (****************************************************************************)
- procedure
- rewrite_config_file;
- begin
- rewrite(textfile);
- writeln(textfile,'ST=',default_stopbits);
- writeln(textfile,'DA=',default_databits);
- writeln(textfile,'PA=',default_parity);
- writeln(textfile,'BA=',default_baud);
- writeln(textfile,'WA=',wait_increment);
- writeln(textfile,'PR=',dial_pre_str);
- writeln(textfile,'PO=',dial_post_str);
- writeln(textfile,'MI=',modem_init_str);
- writeln(textfile,'SY=',speaker_on);
- writeln(textfile,'SN=',speaker_off);
- writeln(textfile,'RT=',redial_time);
- writeln(textfile,'FC=',forced_carrier);
- writeln(textfile,'CT=',carrier_timeout);
- writeln(textfile,'DP=',dial_PATH);
- writeln(textfile,'XO=',XON);
- writeln(textfile,'XF=',XOFF);
- writeln(textfile,'VT=',vt100_mode);
- a_second := round( 3.003004 * wait_increment );
- end;
-
- {$I MUSIC.INC}
- {$I DIRECT.INC}
- {$I TM1.INC}
- (****************************************************************************)
- (* SEND STRING *)
- (****************************************************************************)
- procedure
- send_str( s : strtype );
- var
- i : integer;
- begin
- for i:=1 to length( s ) do
- store_sout_buffer( s[i] );
- end;
- {$I TM2.INC}
- (****************************************************************************)
- (* KEYBOARD HANDLER *)
- (****************************************************************************)
- procedure
- keyboard;
- begin
- if length(a_key) = 1 then begin
- if half_duplex then scrwrite(a_key[1]);
- store_sout_buffer(a_key[1]);
- end
- else
- exec_command(a_key[2]);
- end;
-
- (****************************************************************************)
- (* TERMINAL PROCESSOR *)
- (****************************************************************************)
- procedure
- terminal_processor;
- begin
- if sin_store_ptr <> sin_read_ptr then begin
- kbd_char := read_sin_buffer;
- scrwrite(kbd_char);
- end;
- a_key := inkey;
- if a_key <> '' then keyboard;
- end;
-
- (****************************************************************************)
- (* INITIALIZE FUNCTION KEYS *)
- (****************************************************************************)
- procedure
- initialize_function_keys;
- var
- i : byte;
- begin
- for i:=1 to 40 do func_key^[i]:='';
- assign(keyfile,'TMODEM.KEY');
- {$I-}
- reset(keyfile);
- {$I+}
- ok:=(ioresult = 0);
- if not ok then begin
- rewrite(keyfile);
- for i:=1 to 40 do
- writeln(keyfile,func_key^[i]);
- end
- else begin
- i :=0;
- while ( not eof(keyfile) ) and ( i < 40 ) do begin
- i := i + 1;
- readln(keyfile,func_key^[i]);
- end;
- end;
- close(keyfile);
- end;
-
- (****************************************************************************)
- (* READ CONFIG FILE *)
- (****************************************************************************)
- procedure
- read_config_file;
- var
- teststr : string[2];
- dataval : integer;
- begin
- assign(textfile,'TMODEM.CNF');
- {$I-}
- reset(textfile);
- {$I+}
- ok:=(ioresult = 0);
- if not ok then
- rewrite_config_file
- else begin
- while not eof(textfile) do begin
- readln(textfile,textimage);
- teststr := copy(textimage+' ',1,2);
- upstring(teststr);
- dataval := bval(copy(textimage+' ',4,9));
- delete(textimage,1,3);
- if teststr = 'ST' then default_stopbits := dataval;
- if teststr = 'DA' then default_databits := dataval;
- if teststr = 'PA' then default_parity := dataval;
- if teststr = 'BA' then default_baud := dataval;
- if teststr = 'WA' then wait_increment := dataval;
- if teststr = 'PR' then dial_pre_str := textimage;
- if teststr = 'MI' then modem_init_str := textimage;
- if teststr = 'PO' then dial_post_str := textimage;
- if teststr = 'SN' then speaker_off := textimage;
- if teststr = 'SY' then speaker_on := textimage;
- if teststr = 'RT' then redial_time := dataval;
- if teststr = 'FC' then forced_carrier := textimage;
- if teststr = 'CT' then carrier_timeout := dataval;
- if teststr = 'DP' then dial_PATH := textimage;
- if teststr = 'VT' then vt100_mode := textimage;
- end;
- end;
- close(textfile);
- a_second := round( 3.003004 * wait_increment );
- if vt100_mode = 'T' then silent_mode:=true;
- end;
-
- (****************************************************************************)
- (* MAIN LINE CODE *)
- (****************************************************************************)
- begin
- randomize;
- FGcolor := white;
- BGcolor := black;
- FG := FGcolor;
- BG := BGcolor;
- white_shade := lightgray;
- lowvideo;
- textcolor( FG );
- textbackground( BG );
- window(1,1,80,25);
- clrscr;
- initwin;
- capture_flag := false;
- printer_on := false;
- ascii_mode := false;
- escape_mode := false;
- silent_mode := true;
- monitor_mode := false;
- line_drawing_chars := false;
- time_fix := time;
- dial_time := time_fix;
-
- if base_com_addr = $3F8 then { Setup vectors and port addresses. }
- begin
- turn_IRQ_on := $EF;
- turn_IRQ_off := $10;
- IRQ_vector_ofs := $0030;
- IRQ_vector_seg := $0032;
- end
- else
- begin
- turn_IRQ_on := $F7;
- turn_IRQ_off := $08;
- IRQ_vector_ofs := $002C;
- IRQ_vector_seg := $002E;
- end;
-
- new( sin_buffer_ptr );
- new( sout_buffer_ptr );
- new( xmodem_table_ptr );
- new( func_key );
- sin_store_ptr := 1;
- sin_read_ptr := 1;
- sin_buf_fill_cnt := 0;
- sin_xoff := false;
- sout_store_ptr := 1;
- sout_read_ptr := 1;
- hold_vector_ofs := memw[$0000:IRQ_vector_ofs];
- hold_vector_seg := memw[$0000:IRQ_vector_seg];
- memw[$0000:IRQ_vector_ofs] := ofs(async_intr_handler);
- memw[$0000:IRQ_vector_seg] := CSeg;
- datasegment := DSeg;
- int_enable_reg := base_com_addr + 1;
- int_ident_reg := base_com_addr + 2;
- line_control_reg := base_com_addr + 3;
- modem_control_reg := base_com_addr + 4;
- line_status_reg := base_com_addr + 5;
- modem_status_reg := base_com_addr + 6;
-
- dial_drive := ord(default_drive) - ord('A') + 1;
- getdir(dial_drive,dial_PATH);
- if dial_PATH[length(dial_PATH)] <> '\' then
- dial_PATH := dial_PATH + '\';
- cnf_PATH := dial_PATH;
- read_config_file;
-
- baud := default_baud; { Initialize the serial port. }
- stopbits := default_stopbits;
- databits := default_databits;
- par := default_parity;
- setserial(baud,stopbits,databits,par);
- exit_program := false;
- half_duplex := false;
-
- dial_str := modem_init_str;
- dialer;
- redial_number := '';
- redial_name := '';
- initialize_function_keys;
-
- mkwin(2,2,79,22,'TMODEM, ver 2.3');
- writeln;
- writeln(' If you use this program and like it, a contribution ($20 suggested) will');
- writeln(' be appreciated.');
- writeln;
- writeln;
- writeln(' P & M Software Co.');
- writeln(' 9350 Country Creek #30');
- writeln(' Houston, Texas 77036');
- writeln;
- writeln;
- writeln(' You are encouraged to copy and share this program with others, on the');
- writeln(' condition that the program not be sold for profit, except by the author,');
- writeln(' and that this notice is not altered, bypassed, or removed.');
- writeln;
- writeln(' Good Luck,');
- writeln(' The Author ---> Paul Meiners.');
- writeln;
- escape_win;
- gotoxy(19,23);
- write('Copyright (c) 1985 by: P & M Software Co.');
- reset_win;
-
- write(' Do You Want Music? ');
- repeat
- rand := random;
- until keypressed;
- read(kbd,kbd_char);
- write(kbd_char);
- initialize_music;
- if upcase( kbd_char ) = 'Y' then
- silent_mode := false;
- rmwin;
- sin_store_ptr := sin_read_ptr;
- display_prompts;
-
- delay( wait_increment );
- repeat
- terminal_processor;
- until exit_program;
-
- port[int_enable_reg] := 0; { Turn off modem and reset }
- port[modem_control_reg] := 0; { vectors. }
- port[$21] := port[$21] or turn_IRQ_off;
- memw[$0000:IRQ_vector_ofs] := hold_vector_ofs;
- memw[$0000:IRQ_vector_seg] := hold_vector_seg;
- dispose( func_key );
- dispose( xmodem_table_ptr );
- dispose( sout_buffer_ptr );
- dispose( sin_buffer_ptr );
-
- if capture_flag then toggle_capture_mode;
- window(1,1,80,25);
- gotoxy(1,25);
- clreol;
- write('End of Program.');
- end.